#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/times.h>

void pr_exit(int status) {
	if (WIFEXITED(status)) {
		printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
	} 
	else if (WIFSIGNALED(status)) {
		printf("abnormal termination, signal number = %d\n", WTERMSIG(status));
	}
	else if (WIFSTOPPED(status)) {
		printf("child stopped, signal number = %d\n", WSTOPSIG(status));
	}
}

void pr_times(clock_t real, struct tms *tmstart, struct tms *tmend) {
	static long clktck = 0;
	if (clktck == 0) {
		if ((clktck=sysconf(_SC_CLK_TCK)) < 0) {
			printf("sysconf error: %s\n", strerror(errno));
			return;
		}	
	}

	printf(" real: %7.2f\n", real/(double)clktck);
	printf(" user: %7.2f\n", (tmend->tms_utime - tmstart->tms_utime) / (double)clktck);
	printf(" sys: %7.2f\n", (tmend->tms_stime - tmstart->tms_stime) / (double)clktck);
	printf(" child user: %7.2f\n", (tmend->tms_cutime - tmstart->tms_cutime) / (double)clktck);
	printf(" child sys: %7.2f\n", (tmend->tms_cstime - tmstart->tms_cstime) / (double)clktck);
}

void do_cmd(char* cmd) {
	struct tms tmstart, tmend;
	clock_t start, end;
	int status;

	printf("\ncommand: %s\n", cmd);

	if ((start=times(&tmstart)) == -1) {
		printf("times error: %s\n", strerror(errno));
		return;
	}	

	if ((status=system(cmd)) < 0) {
		printf("system error: %s\n", strerror(errno));
		return;
	}

	if ((end=times(&tmend)) == -1) {
		printf("times error: %s\n", strerror(errno));
		return;
	}	

	pr_times(end-start, &tmstart, &tmend);
	pr_exit(status);
}

int main(int argc, char* argv[]) {
	int i;
	setbuf(stdout, NULL);
	for (i = 1; i < argc; ++i) {
		do_cmd(argv[i]);
	}

	return 0;
}